package router

import (
	"CommonsProject/pkg/tools/redisTool"
	"CommonsProject/router/generatorRouter"
	"CommonsProject/router/systemRouter"
	"context"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"log"
	"net/http"
	"time"
)

// RouterInit 初始化路由
func RouterInit(db *gorm.DB) *gin.Engine {
	router := gin.Default()
	router.SetTrustedProxies([]string{"127.0.0.1"})

	//开启CORS访问
	router.Use(cORSMiddleware())
	//开启权限验证
	router.Use(authorityVerify())
	//全局处理
	router.Use(handleError())

	{
		//系统管理模块
		systemRouter.RouterManager(router, db)
		//生成管理
		generatorRouter.RouterManager(router, db)

	}

	return router
}

// authorityVerify 权限验证
func authorityVerify() gin.HandlerFunc {

	var authorityMap map[string]string

	//10秒更新一次权限信息
	go func(authorityMap *map[string]string) {
		for {
			<-time.Tick(time.Second * 10)
			background := context.Background()
			result, _ := redisTool.ClientRedis.HGetAll(background, redisTool.SYSTEM_AUTHORITY).Result()
			bytes, _ := json.Marshal(result)
			_ = json.Unmarshal(bytes, authorityMap)
		}
	}(&authorityMap)

	return func(ctx *gin.Context) {
		uri := ctx.Request.RequestURI
		//todo 没有坐完，先把权限控制的api做完
		log.Println(uri)
	}
}

// cORSMiddleware 初始跨域问题
func cORSMiddleware() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		//允许所有的来源访问
		ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		ctx.Writer.Header().Set("Access-Control-Allow-Headers", "*")
		ctx.Writer.Header().Set("Access-Control-Allow-Methods", "*")
		ctx.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		//放行
		ctx.Next()
	}
}

// 处理错误
func handleError() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		defer func() {
			//发生异常
			if err := recover(); err != nil {
				var msg string
				switch err.(type) {
				case error:
					msg = err.(error).Error()
					break
				default:
					msg = fmt.Sprint(err)
					break
				}

				//返回响应内容
				ctx.JSON(http.StatusOK, gin.H{
					"code": 500,
					"msg":  msg,
					"data": nil,
				})

				//终止请求
				ctx.Abort()
			}
		}()
		ctx.Next()
	}
}
